using SQLRunnerLib.Services;
using SQLServices.Runners;
using SQLServices.Runners.Events;

namespace SQLRunnerLib.TransMgr
{
    /// <summary>
    /// This was the default transaction behaviour that was designed originally in 
    /// SQLRunner. One single conenction was created for the whole execution and there 
    /// is not transaction created during the execution. This approach
    /// provides the better performance but it completely relays in how well the scripts
    /// are written.
    /// The execution of the scripts using this manager is like if you were opening a query 
    /// window in SSMS and pasting the context of each script one by one between executions.
    /// </summary>
    /// <remarks>
    /// Possible problems are:
    /// [1] If a script begins a transaction and it is not commited the following scripts 
    /// are executed in that same transaction, when the connection is closed all the updates are rollback
    /// [2] Scripts are commited so if an error takes place there is not way to rollback any of the commited scripts.
    /// [3] Execution of the scripts is not stopped if an exception occurs.
    /// </remarks>
    class OptimisticConnMgr:AbstractManager
    {
        public OptimisticConnMgr(IRunner runner) : base(runner){ }

        #region Runner Event Handlers

        /// <summary>
        /// When the Runner has finished the execution of all scripts it calls this method.
        /// This is where the connection is closed.
        /// </summary>
        protected override void OnExecutionFinished(object sender, ExecutionFinishedEventArgs e)
        {
            CleanConnection();
        }

        /// <summary>
        /// Called when an exception is returned when a script is executed. This manager does
        /// not take any action when an exception occurs.
        /// </summary>
        protected override void OnScriptError(object sender, ScriptExecutionErrorEventArgs e)
        {
            return;
        }

        /// <summary>
        /// The runner triggers this event after the execution of each script. This manager
        /// does not take any action when it happens.
        /// </summary>
        protected override void OnScriptExecuted(object sender, ScriptExecutedEventArgs e)
        {
            return;
        }
        #endregion

        /// <summary>
        /// Hook into the execution process that runs before the execution takes place. In this
        /// implementation this method does nothing.
        /// </summary>
        protected override void DoAfterExecution()
        {
            return;
        }

        /// <summary>
        /// Hook into the execution process that runs just after the execution of the script.
        /// It checks if a connection is available just before the script is executed.
        /// </summary>
        protected override void DoBeforeExecution()
        {
            if (_mainConn != null) return;
            _mainConn = ServiceContainer.SQLConnection.GetDatabase().Clone();
            LogMsg("Connection was created");
        }
    }
}
